import numpy as np
from django.http import JsonResponse
from django.shortcuts import render

from apps.PO.CoursePO import CoursePO
from apps.PO.StudentPO import StudentPO
from apps.PO.UserPO import UserPO
from apps.Service.CourseService import CourseService
from apps.Service.StudentService import StudentService
from apps.Service.UserService import UserService


# 获取用户信息并返回用户信息页面
def user_info(request):
    # 获取用户信息
    user_po = UserPO()
    # 实例化服务层
    user_service = UserService(user_po)
    # 调用服务层方法获取用户信息
    result = user_service.get_user_info()
    # 获取dataframe的列名
    columns = result.columns.tolist()
    # 将dataframe每一行记录转为元组列表
    result = [tuple(x) for _, x in result.iterrows()]
    response = {
        'columns': columns,
        'datas': result
    }
    # 处理结果并返回页面
    if result:
        return render(request, 'user_info.html', response)
    else:
        return render(request, 'user_info.html', response)


# 获取课程信息并返回课程信息页面
def course_info(request):
    # 获取课程信息
    course_po = CoursePO()
    # 实例化服务层
    course_service = CourseService(course_po)
    # 调用服务层方法获取课程信息
    data = course_service.get_all_courses()
    # 将dataframe每一行记录转为元组列表
    result = [tuple(x) for _, x in data.iterrows()]
    response = {
        'columns': data.columns.tolist(),
        'datas': result
    }
    # 处理结果并返回页面
    if result:
        return render(request, 'course_info.html', response)
    else:
        return render(request, 'course_info.html', response)


# 登录注册页面
def login_register(request):
    return render(request, 'login_register.html')


# 学生群体可视化界面
def visualize(request):
    # 读取所有学生数据
    student_po = StudentPO()
    student_service = StudentService(student_po)
    data = student_service.get_all_students()
    # 读取所有课程数据
    course_po = CoursePO()
    course_service = CourseService(course_po)
    course_data = course_service.get_all_courses()

    # 两个数据以course_name为key进行合并
    data = data.merge(course_data, on='course_name')

    # 统计各个cat类别下的course_name数量
    course_type_count = {}
    for _, x in data.iterrows():
        course_type = x['cat']
        if course_type in course_type_count:
            course_type_count[course_type] += 1
        else:
            course_type_count[course_type] = 1

    # 统计学生课程的平时成绩、期末成绩、总成绩、绩点平均值
    avg_com_grade = data['com_grade'].mean()
    avg_end_grade = data['end_grade'].mean()
    avg_total_grade = data['total_grade'].mean()
    avg_grade_point = data['grade_point'].mean()

    # 统计每个cat下的教师数量,key为cat值，值为数量
    teacher_count = {}
    for _, x in data.iterrows():
        teacher_name = x['teacher']
        if teacher_name in teacher_count:
            teacher_count[teacher_name] += 1

        else:
            teacher_count[teacher_name] = 1

    # 统计教师任课数量占比
    teacher_count_percent = {}
    for key, value in teacher_count.items():
        teacher_count_percent[key] = np.round(value / len(data) * 100, 0)
    print(teacher_count_percent)

    response = {
        'columns': data.columns.tolist(),
        'datas': data.values.tolist(),
        'course_type_count': course_type_count,
        'avg_com_grade': avg_com_grade,
        'avg_end_grade': avg_end_grade,
        'avg_total_grade': avg_total_grade,
        'avg_grade_point': avg_grade_point,
        'teacher_count': teacher_count,
        'teacher_count_percent': teacher_count_percent,

    }
    return render(request, 'class_visualize.html', response)


# 学生画像信息界面
def stu_info(request):
    # 实例化学生PO
    student_po = StudentPO()
    # 实例化学生服务层
    student_service = StudentService(student_po)
    # 调用服务层方法获取学生画像信息
    data = student_service.get_all_students()
    # 将返回的dataframe的每条记录赋值为student_po对象
    result = []
    for _, x in data.iterrows():
        student_po.set_student_info(x)
        result.append(student_po.get_student_info())

    response = {
        'columns': data.columns.tolist(),
        'datas': result
    }
    # 处理结果并返回页面
    if result:
        return render(request, 'stu_info.html', response)
    else:
        return JsonResponse("None")


# 单个学生画像信息界面
def portrait(request):
    # 获取学生id
    stu_id = request.GET.get('stu_id')
    # 实例化学生PO
    student_po = StudentPO(stu_id=stu_id)
    # 实例化学生服务层
    student_service = StudentService(student_po)
    # 调用服务层方法获取学生画像信息
    data = student_service.get_student_by_id()
    # 将返回的元组赋值为student_po对象
    result = []

    # 根据课程名称获取课程信息
    course_types = []
    # 遍历字典
    for x in data:
        # 实例化学生PO
        student_po.set_stu_id(x[0])
        student_po.set_stu_name(x[1])
        student_po.set_course_name(x[2])
        student_po.set_com_grade(x[3])
        student_po.set_end_grade(x[4])
        student_po.set_total_grade(x[5])
        student_po.set_grade_point(x[6])
        result.append(student_po.get_student_info())

        # 实例化课程PO
        course_po = CoursePO(course_name=student_po.get_course_name())
        course_service = CourseService(course_po)
        # 调用服务层方法获取课程类别
        course_type = tuple(course_service.get_course_by_name())
        course_type = course_type[0][1]
        course_types.append(course_type)

    # 统计课程类别中各个类型的数量,key为course_type,值为课程类别，key为num，值为数量
    course_type_count = {}
    for course_type in course_types:
        if course_type in course_type_count:
            course_type_count[course_type] += 1
        else:
            course_type_count[course_type] = 1
    # 课程类别百分比字典
    course_type_counts = []
    for key, value in course_type_count.items():
        course_object = {}
        course_object['course_type_'] = key
        course_object['number'] = value
        course_object['num'] = np.round(value / len(course_types) * 100, 0)
        course_type_counts.append(course_object)
    # 统计总修读课程数
    total_course = len(result)

    # 计算平均学分绩点
    total_grade_point = 0
    total_com_grade = 0
    total_end_grade = 0
    total_total_grade = 0
    for x in data:
        total_grade_point += x[6]
        total_com_grade += x[3]
        total_end_grade += x[4]
        total_total_grade += x[5]

    # 统计绩点位于2分以下、3分以上、2~3分的记录

    low_grade_count = 0
    mid_grade_count = 0
    high_grade_count = 0
    for x in data:
        if x[6] < 3:
            low_grade_count += 1
        elif x[6] >= 4:
            high_grade_count += 1
        else:
            mid_grade_count += 1

    # 计算平均学分绩点
    avg_grade_point = np.round(total_grade_point / len(result), 2)
    # 计算平均平时成绩
    avg_com_grade = np.round(total_com_grade / len(result), 2)
    # 计算平均期末成绩
    avg_end_grade = np.round(total_end_grade / len(result), 2)
    # 计算平均总成绩
    avg_total_grade = np.round(total_total_grade / len(result), 2)

    response = {
        'datas': result,
        "stu_name": student_po.get_stu_name(),
        "total_course": total_course,
        "course_type_counts": course_type_counts,
        "avg_grade_point": avg_grade_point,
        "avg_com_grade": avg_com_grade,
        "avg_end_grade": avg_end_grade,
        "avg_total_grade": avg_total_grade,
        # 绩点分布
        "low_grade_count": low_grade_count,
        "mid_grade_count": mid_grade_count,
        "high_grade_count": high_grade_count,
    }
    # 处理结果并返回页面
    if result:
        return render(request, 'component/portrait.html', response)
    else:
        return JsonResponse("None")
